﻿using DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement;
using DeviceFaultPushService.DeviceProcessManagement.CommunicationManagement.Models;
using DeviceFaultPushService.MessagePushService;
using DeviceFaultPushService.SystemService;
using System.Text.Json;

namespace DeviceFaultPushService.DeviceProcessManagement.OperationManagement;

/// <summary>
/// 运行服务
/// </summary>
public class RunningServices
{
    private List<string> runningId = new();

    /// <summary>
    /// 日志委托
    /// </summary>
    public delegate void LogDelegate(string log);
    /// <summary>
    /// 日志事件
    /// </summary>
    public event LogDelegate LogEvent;
    /// <summary>
    /// 日志
    /// </summary>
    /// <param name="log"></param>
    public void Log(string log)
    {
        if (LogEvent is not null)
        {
            LogEvent(log);
        }
    }

    /// <summary>
    /// 在运行列表
    /// </summary>
    public List<string> RunningId
    {
        get
        {

            return runningId;
        }
    }

    /// <summary>
    /// 操作委托
    /// </summary>
    /// <param name="status"></param>
    public delegate void ConnectionDisconnectedEventDelegate(string id);
    /// <summary>
    /// 操作事件
    /// </summary>
    /// <param name="status"></param>
    public event ConnectionDisconnectedEventDelegate CloseEvent;
    /// <summary>
    /// 操作事件
    /// </summary>
    /// <param name="status"></param>
    public event ConnectionDisconnectedEventDelegate RunningEvent;

    public void Start(string conf)
    {
        //配置文件序列化
        DeviceInformationModel deviceInformation = JsonSerializer.Deserialize<DeviceInformationModel>(conf);
        //检查是否在运行
        if (runningId.Contains(deviceInformation.Number) == false)
        {
            //开启新线程
            new Task(() =>
            {
                //启动设备服务
                StartDeviceServices(deviceInformation.Protocol, conf);

            }).Start();
        }
    }

    private void StartDeviceServices(ProtocolEnum protocol, string conf)
    {
        //构造连接对象
        IDeviceCommunication deviceCommunication = null;
        if (protocol == ProtocolEnum.SiemensS7)
        {
            CommunicationManagement.SiemensS7.Models.DeviceInformationModel deviceInformation = JsonSerializer.Deserialize<CommunicationManagement.SiemensS7.Models.DeviceInformationModel>(conf);
            deviceCommunication = new CommunicationManagement.SiemensS7.DeviceCommunication(deviceInformation);
        }
        if (protocol == ProtocolEnum.ModbusTcp)
        {
            CommunicationManagement.ModbusTcp.Models.DeviceInformationModel deviceInformation = JsonSerializer.Deserialize<CommunicationManagement.ModbusTcp.Models.DeviceInformationModel>(conf);
            deviceCommunication = new CommunicationManagement.ModbusTcp.DeviceCommunication(deviceInformation);
        }
        try
        {
            //连接设备
            deviceCommunication.Connect();
            if (deviceCommunication.IsConnected == false)
            {
                Log($"服务异常   编号：{deviceCommunication.Id}   协议：{protocol}   设备：{deviceCommunication.Name}   信息：服务开启失败");
                DisconnectAndReconnect(conf);
                return;
            }
            //添加设备id
            runningId.Add(deviceCommunication.Id);
            Log($"服务开启   编号：{deviceCommunication.Id}   协议：{protocol}   设备：{deviceCommunication.Name}");
            if (RunningEvent is not null)
            {
                RunningEvent(deviceCommunication.Id);
            }
            //报警地址列表
            SortedList<string, FaultInformationModel> addrList = new();
            //消息推送服务
            MessagePush messagePush = new MessagePush();
            messagePush.LogEvent += Log;

            while (true)
            {
                //检查运行权限 false 结束线程
                if (runningId.Contains(deviceCommunication.Id) == false)
                {
                    deviceCommunication.Close();
                    Stop(deviceCommunication.Id);
                    Log($"服务关闭   编号：{deviceCommunication.Id}   协议：{protocol}   设备：{deviceCommunication.Name}");
                    break;
                }
                if (deviceCommunication.IsConnected == false)
                {
                    Thread.Sleep(GetConfiguration.Configuration.CollectionInterval * 1000);
                    deviceCommunication.Close();
                    Stop(deviceCommunication.Id);
                    DisconnectAndReconnect(conf);
                    break;
                }
                //获取报警状态
                deviceCommunication.Read(out var result);
                if (result is null)
                {
                    Thread.Sleep(GetConfiguration.Configuration.CollectionInterval * 1000);
                    deviceCommunication.Close();
                    Stop(deviceCommunication.Id);
                    Log($"服务关闭   编号：{deviceCommunication.Id}   协议：{protocol}   设备：{deviceCommunication.Name}   信息：服务关闭，无有效数据地址");
                    break;
                }
                foreach (var item in result)
                {
                    //确认是否已经存在报警
                    if (addrList.ContainsKey(item.Uid))
                    {
                        //获取当前时间的时间戳（秒为单位）  
                        long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
                        FaultInformationModel alarmInformation = addrList[item.Uid];
                        //报警间隔
                        if (alarmInformation.StartTimestamp < timestamp)
                        {
                            //确认是否存在报警
                            if (item.Value)
                            {
                                //报警信息处理
                                //默认人员级别 为 1 管理 为 0 同一报警 2 次，一次管理报警
                                if (alarmInformation.Count % 3 == 0)
                                {
                                    messagePush.Receive(deviceCommunication.Contacts, deviceCommunication.Name, item.Message, MessagePushService.Models.UserLevelEnum.Administration);
                                }
                                else
                                {
                                    messagePush.Receive(deviceCommunication.Contacts, deviceCommunication.Name, item.Message);
                                }
                                //报警计数
                                alarmInformation.Count++;
                                //重新赋值
                                alarmInformation.StartTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds() + GetConfiguration.Configuration.AlarmInterval;
                            }
                            else
                            {
                                addrList.Remove(item.Uid);
                            }
                        }
                    }
                    else if (item.Value)
                    {
                        //添加新的报警
                        addrList.Add(item.Uid, new FaultInformationModel()
                        {
                            Uid = item.Uid,
                            Count = 2,
                            //获取当前时间的UTC时间戳（秒为单位）
                            StartTimestamp = DateTimeOffset.Now.ToUnixTimeSeconds() + GetConfiguration.Configuration.AlarmInterval,
                        });
                        //报警通知
                        messagePush.Receive(deviceCommunication.Contacts, deviceCommunication.Name, item.Message);
                    }
                }

                Thread.Sleep(GetConfiguration.Configuration.CollectionInterval * 1000);
            }
        }
        catch (Exception ex)
        {
            deviceCommunication.Close();
            Stop(deviceCommunication.Id);
            Log($"服务异常   编号：{deviceCommunication.Id}   协议：{protocol}   设备：{deviceCommunication.Name}   信息：{ex.Message}");
            DisconnectAndReconnect(conf);
        }
    }

    public void Stop(string number)
    {
        //检查是否在运行
        if (runningId.Contains(number))
        {
            runningId.Remove(number);

            if (CloseEvent is not null)
            {
                CloseEvent(number);
            }
        }
    }

    /// <summary>
    /// 断线重连服务
    /// </summary>
    private void DisconnectAndReconnect(string conf)
    {
        new Task(() =>
        {
            //断线重连服务

            //配置文件序列化
            DeviceInformationModel deviceInformation = JsonSerializer.Deserialize<DeviceInformationModel>(conf);
            Log($"服务异常   编号：{deviceInformation.Number}   协议：{deviceInformation.Protocol}   设备：{deviceInformation.Name}    信息：设备正在尝试断线重连服务！");
            try
            {
                //序列化接口
                IDeviceCommunication deviceCommunication = null;
                if (deviceInformation.Protocol == ProtocolEnum.SiemensS7)
                {
                    deviceCommunication = new CommunicationManagement.SiemensS7.DeviceCommunication(JsonSerializer.Deserialize<CommunicationManagement.SiemensS7.Models.DeviceInformationModel>(conf));
                }
                if (deviceInformation.Protocol == ProtocolEnum.ModbusTcp)
                {
                    //deviceCommunication = new CommunicationManagement.ModbusTcp.DeviceCommunication(JsonSerializer.Deserialize<CommunicationManagement.ModbusTcp.Models.DeviceInformationModel>(conf));
                }

                //是否成功
                bool isSuccess = false;
                //尝试3次重连
                for (int i = 1; i <= 3; i++)
                {
                    //连接设备
                    Log($"服务异常   编号：{deviceInformation.Number}   协议：{deviceInformation.Protocol}   设备：{deviceInformation.Name}    信息：尝试断线重连服务第：{i}次！");

                    try
                    {
                        deviceCommunication.Connect();

                        if (deviceCommunication.IsConnected)
                        {
                            Log($"服务通知   编号：{deviceInformation.Number}   协议：{deviceInformation.Protocol}   设备：{deviceInformation.Name}    信息：尝试断线重连服务第：{i}次，重连服务成功，尝试开启服务！");
                            isSuccess = true;
                            deviceCommunication.Close();
                            break;
                        }
                    }
                    catch (Exception)
                    {

                    }
                    //每次重连服务间隔15秒
                    Thread.Sleep(15 * 1000);
                }
                if (isSuccess)
                {
                    StartDeviceServices(deviceInformation.Protocol, conf);
                }
                else
                {
                    Log($"服务通知   编号：{deviceInformation.Number}   协议：{deviceInformation.Protocol}   设备：{deviceInformation.Name}   信息：尝试断线重连服务第：3次，重连服务失败，服务已经自动关闭，请尝试手动重新开启服务！");
                }
            }
            catch (Exception ex)
            {
                Log($"服务异常   编号：{deviceInformation.Number}   协议：{deviceInformation.Protocol}   设备：{deviceInformation.Name}   信息：{ex.Message}");
            }
        }).Start();
    }

}